/**
 * COPYRIGHT. Harry Wu 2011. ALL RIGHTS RESERVED.
 * Project: just-core
 * Author: Harry Wu <harrywu304@gmail.com>
 * Created On: Jun 19, 2011 2:23:13 PM
 *
 */
package org.justframework.api.connector;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.codehaus.jackson.annotate.JsonIgnore;




/**
 * rest style request bean interface
 * if any get method with no pojo property added, @JsonIgnore is needed, or json bean mapping will fail
 */
public class Request {
	
	/**
	 * request id
	 */
	private String requestId = UUID.randomUUID().toString();

	/**
	 * request resource
	 */
	private URI uri;
	
	/**
	 * request method, identify the semantic of request
	 */
	private String requestMethod;
	
	/**
	 * resource represent type 
	 */
	private String representType;
	
	/**
	 * request params
	 */
	private Map<String,Object> params = new HashMap<String,Object>();
	
	/**
	 * headers for specified communication protocol
	 */
	private Map<String,Object> headers = new HashMap<String,Object>();
	
	/**
	 * control options
	 */
	private Map<String,Object> options = new HashMap<String,Object>();
	
	/**
	 * connect timout
	 */
	private long connectTimeout = 1000L;
	
	/**
	 * operation timeout
	 */
	private long operateTimeout = 5000L;
	
	/**
	 * request timestamp
	 */
	private long requestTimestamp;
	
	private String[] routeKeys;
	
	/**
	 * @param requestId the requestId to set
	 */
	public void setRequestId(String requestId) {
		this.requestId = requestId;
	}

	/**
	 * @return the requestId
	 */
	public String getRequestId() {
		return requestId;
	}

	public URI getUri() {
		return uri;
	}

	public void setUri(URI uri) {
		this.uri = uri;
	}

	public Map<String, Object> getParams() {
		return params;
	}

	public void setParams(Map<String, Object> params) {
		this.params = params;
	}
	
	/**
	 * add request param
	 * @param key
	 * @param value
	 * @return
	 */
	public Request addParam(String key, Object value){
		params.put(key, value);
		return this;
	}

	public Map<String, Object> getOptions() {
		return options;
	}

	public void setOptions(Map<String, Object> options) {
		this.options = options;
	}

	public String getRequestMethod() {
		return requestMethod;
	}

	public void setRequestMethod(String requestMethod) {
		this.requestMethod = requestMethod;
	}

	public long getConnectTimeout() {
		return connectTimeout;
	}

	public void setConnectTimeout(long connectTimeout) {
		this.connectTimeout = connectTimeout;
	}

	public long getOperateTimeout() {
		return operateTimeout;
	}

	public void setOperateTimeout(long operateTimeout) {
		this.operateTimeout = operateTimeout;
	}
	
	public <T> T getParam(String paramName) {
		return (T)params.get(paramName);
	}
	
	public <T> void setParam(String paramName, T paramValue) {
		params.put(paramName, paramValue);
	}
	
	public long getRequestTimestamp() {
		return requestTimestamp;
	}

	public void setRequestTimestamp(long requestTimestamp) {
		this.requestTimestamp = requestTimestamp;
	}
	
	public String getRepresentType() {
		return representType;
	}

	public void setRepresentType(String representType) {
		this.representType = representType;
	}

	public Map<String, Object> getHeaders() {
		return headers;
	}

	public void setHeaders(Map<String, Object> headers) {
		this.headers = headers;
	}
	
	/**
	 * @return the routeKeys
	 */
	public String[] getRouteKeys() {
		return routeKeys;
	}

	/**
	 * @param routeKeys the routeKeys to set
	 */
	public void setRouteKeys(String[] routeKeys) {
		this.routeKeys = routeKeys;
	}

	@Override
	public String toString(){
		StringBuilder result = new StringBuilder();
		result.append("requestId:"+requestId).append(",");
		result.append("uri:"+uri).append(",");
		result.append("requestMethod:"+requestMethod).append(",");
		result.append("representType:"+representType).append(",");
		result.append("params:"+params).append(",");
		result.append("headers:"+headers).append(",");
		result.append("options:"+options).append(",");
		result.append("connectTimeout:"+connectTimeout).append(",");
		result.append("operateTimeout:"+operateTimeout).append(",");
		result.append("requestTimestamp:"+requestTimestamp);
		return result.toString();	
	}

	public void setUriString(String uri){
		try {
			setUri(new URI(uri));
		} catch (URISyntaxException e) {
			throw new RuntimeException(e);
		}
	}

}